#ifndef __CLAVESECUNDARIA_H__
#define __CLAVESECUNDARIA_H__

#include "Tipos.h"


/**********************ESTRUCTURA DEL ARCHIVO ********************/
/*	#REGISTROS NROBLOQUE_SIG  CODIGOS......						 */
/*****************************************************************/
/******EL INDICE*********/
/*
CLAVE #INDICE_VECTOR VECTOR[]  (el ultimo item indica el bloque siguiente)
*/

class CClaveSecundaria
{
public:
	string clave;
	vector<TIPO_DATO> codProductos;//numero de bloque de lista del codigos de productos	
	int m_indice;
	TIPO_DATO codProd;
	CClaveSecundaria(string registro,bool nombre);
	CClaveSecundaria(){}
	~CClaveSecundaria(){}
	//trasformar(char &dato[]) //con todo el char
	TIPO_DATO getCodProducto(){return codProd;}
	TIPO_DATO getCodProducto(int indice){return codProductos[indice];}
	TIPO_DATO getCodProd(int indice);
	TIPO_DATO getTamanio(){return (TIPO_DATO)(clave.length()+TAMANIO_BYTE_DIN + TAMANIO_BYTE_LISTA+sizeof(TIPO_DATO)*CANT_CODIGOS);}	
	TIPO_DATO getTamanioNodo(){return (TIPO_DATO)(clave.length()+TAMANIO_BYTE_DIN );}
	string getClave(){return clave;}
	bool obtenerNroBloque(TIPO_DATO &nroBloqueOut,fstream &archivo){return true;}	
	int getIndice(){return m_indice;}
	void setIndice(int indice){m_indice =indice;}
	int transformar(string datos, TIPO_DATO &pos);
	string desTransformar();
	string desTransformarNodo();
	int transformarNodo(string datos, TIPO_DATO &pos);
	void ordenar();
	void mostrar();
	void insertarVectorSec(TIPO_DATO codProdIn,fstream &archivo);
	bool eliminarElemVector(TIPO_DATO claveIn,fstream &archivo){return false;}	
	//OPERADORES
	CClaveSecundaria &operator=(CClaveSecundaria & clave);
	bool operator==(const CClaveSecundaria &clave) const;
	bool operator<(const CClaveSecundaria &clave) const;	
	
	//FIN DE OPERADORES
    bool operator()(CClaveSecundaria& inicio, CClaveSecundaria& fin)
    {
    	if(inicio.getClave().compare(fin.getClave()))
    		return true;
    	return false;
    }
};

/*-----------------------------------------------------------*/
CClaveSecundaria::CClaveSecundaria(string registro,bool nombre=true)
{
	int tamanio=0,posicion=0;

	//atoi(registro.substr(0,5).c_str());
	this->codProd= atoi(registro.substr(0,5).c_str());
	//this->codProductos[0] = atoi(registro.substr(0,5).c_str());
	this->codProductos.push_back(atoi(registro.substr(0,5).c_str()));
	posicion=5;

	tamanio 	= 	string2TipoDato(registro.substr(posicion,TAMANIO_BYTE_DIN));
	posicion 	+= 	TAMANIO_BYTE_DIN;
	this->clave = 	registro.substr(posicion,tamanio);
	posicion 	+= 	tamanio;
	this->m_indice=1;
	if(nombre) //si la clave es con el nombre lo leo y eso es lo que guardo
	{
		tamanio = string2TipoDato(registro.substr(posicion,TAMANIO_BYTE_DIN));
		posicion +=TAMANIO_BYTE_DIN;
		clave= registro.substr(posicion,tamanio);
	}
}
/*-----------------------------------------------------------*/
void CClaveSecundaria::mostrar() /* = std::cout*/
{				
	cout<<"\tClave: -"<<clave<<"-"<<endl;	
	cout<<"Esta presente en los siguientes productos: "<<endl;	
	for(int i=0;i<m_indice;i++)	
		cout<<"codigo NRO "<<i<<" : "<<this->codProductos[i]<<endl;
	//cout<<endl;
}
/*-----------------------------------------------------------*/
int CClaveSecundaria::transformar(string datos, TIPO_DATO &posicion)
{
	int cantByte =0;
	int i;
	TIPO_DATO tamanioDatos=0;
	cantByte = string2TipoDato(datos.substr(posicion,TAMANIO_BYTE_DIN));	
	tamanioDatos +=cantByte;
	posicion+=TAMANIO_BYTE_DIN;
	clave = datos.substr(posicion,cantByte);
	posicion+=cantByte;
	m_indice =string2TipoDato(datos.substr(posicion,TAMANIO_BYTE_LISTA));
	if(m_indice ==4 )
		cout<<"entro"<<endl;
	posicion+=TAMANIO_BYTE_LISTA;
	for(i=0;i<m_indice;i++)
	{
		codProductos.push_back(string2TipoDato(datos.substr(posicion,TAMANIO_COD_PROD)));
		posicion+= TAMANIO_COD_PROD;
		//tamanioDatos+=TAMANIO_COD_PROD;
	}
/*	
	if(m_indice ==3)
	{
		cout<<"Clave : "<<clave<<endl;
		for(int j=0;j<3;j++)
			cout<<">>>>>><<<<<<<<<<<<CHEQUEO"<<codProductos[j]<<endl;
		cout<<endl;
	}
*/	
	//esto es porque el vector es estatico
	for(;i<CANT_CODIGOS;i++)
		posicion+= TAMANIO_COD_PROD;
	
	return tamanioDatos +  TAMANIO_BYTE_DIN +TAMANIO_BYTE_LISTA +CANT_CODIGOS*TAMANIO_COD_PROD;
} 
/*-----------------------------------------------------------*/
string CClaveSecundaria::desTransformar()
{
	string dato="";
	int i;
	dato+=convertirChar((int)clave.length(),TAMANIO_BYTE_DIN);
	dato+=clave;
	dato+=convertirChar(m_indice,TAMANIO_BYTE_LISTA);
/*	if(m_indice ==4 )
		cout<<"entro"<<endl;
	if(m_indice ==3 )
	{
		cout<<"Clave : "<<clave<<endl;
		for(int j=0;j<3;j++)
			cout<<">>>>>><<<<<<<<<<<<CHEQUEO"<<codProductos[j]<<endl;
		cout<<endl;
	}
*/	
	for(i=0;i<m_indice;i++)	
		//dato+=itoa(codProductos[m_indice],numero,10);
		dato+=convertirChar(codProductos[i],TAMANIO_COD_PROD);
	for(;i<CANT_CODIGOS;i++)
		dato+="0000";
	//dato+=itoa((int)clave.length(),numero,10);
	return dato;
}

/*-----------------------------------------------------------*/
int CClaveSecundaria::transformarNodo(string datos, TIPO_DATO &posicion)
{
	int cantByte =0;
	TIPO_DATO tamanioDatos=0;
	cantByte = string2TipoDato(datos.substr(posicion,TAMANIO_BYTE_DIN));	
	tamanioDatos +=cantByte;
	posicion+=TAMANIO_BYTE_DIN;
	clave = datos.substr(posicion,cantByte);
	posicion+=cantByte;
	this->m_indice = 0;

	return tamanioDatos +  TAMANIO_BYTE_DIN +TAMANIO_BYTE_LISTA ;
} 
/*-----------------------------------------------------------*/
string CClaveSecundaria::desTransformarNodo()
{
	string dato="";	
	dato+=convertirChar((int)clave.length(),TAMANIO_BYTE_DIN);
	dato+=clave;
	//dato+=convertirChar(m_indice,TAMANIO_BYTE_LISTA);
	return dato;
}

/*-----------------------------------------------------------*/
CClaveSecundaria &CClaveSecundaria::operator=(CClaveSecundaria & key)
{
	if(this==&key)
		return *this;
	this->clave = key.clave;
	this->m_indice =key.getIndice();
	this->codProductos.clear();
//	for(int i=0;i<this->m_indice;i++)
//		cout<<"COPIAR ANTES::"<<key.codProductos[i]<<endl;
	for(int i=0;i<this->m_indice ;i++)	
		this->codProductos.push_back( key.codProductos[i]);
		
//	for(int i=0;i<this->m_indice;i++)
//		cout<<"COPIAR DESPUES::"<<this->codProductos[i]<<endl;

	return *this;	
}
/*-----------------------------------------------------------*/
bool CClaveSecundaria::operator==(const CClaveSecundaria &key)const
{
	return (clave).compare(key.clave)==0;
}
/*-----------------------------------------------------------*/
bool CClaveSecundaria::operator<(const CClaveSecundaria &key) const
{
	return (clave).compare(key.clave)==-1;
}
/*-----------------------------------------------------------*/

//VER SI PUEDE ENTRAR UN REGISTRO CON EL MISMO ID !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
void CClaveSecundaria::insertarVectorSec(TIPO_DATO codProdIn,fstream &archivo)
{
	char bloque[TAMANIO_LISTA_COD]={};
	string dato="";
	TIPO_DATO cantMaxCod;
	TIPO_DATO nroBloqueAux;

	//archivo.seekg(TAMANIO_LISTA_COD*nrobloque,ios::beg);
	//archivo.read(bloque,TAMANIO_LISTA_COD);
if(clave.compare("341")==0)
cout<<""<<endl;
	if(this->m_indice==(CANT_CODIGOS))
	{
		//escribir en el archivo de listados
		TIPO_DATO codAux;		

		//el ultimo registro se guarda para concatenar los distintos bloques para formar la lista de codigos
		cantMaxCod = (TAMANIO_LISTA_COD-1)/TAMANIO_COD_PROD ;//cant max de codigos en el bloque de lista
		for(int i=0;i<(m_indice-1) ;i++)
		{
			if(codProductos[i]>codProdIn)
			{
				//fin=true;
				codAux=codProductos[i];
				codProductos[i] = codProdIn;
				codProdIn = codAux;
			}
		}
		if(m_indice ==3 && clave.compare("341")==0)
		{
			cout<<"Clave : "<<clave<<endl;
			for(int i=0 ; i<3;i++)
				cout<<"ENTRADA :"<<codProductos[i]<<endl;
			cout<<"entro"<<endl;
		}

		nroBloqueAux = codProductos[m_indice-1];
		archivo.seekg(TAMANIO_LISTA_COD*nroBloqueAux,ios::beg);
		archivo.read(bloque,TAMANIO_LISTA_COD);		
		while(cantMaxCod==((TIPO_DATO)(bloque[0])))
		{
			dato.append(bloque);
			nroBloqueAux = string2TipoDato(dato.substr(1,TAMANIO_COD_PROD));
			archivo.seekg(TAMANIO_LISTA_COD*nroBloqueAux ,ios::beg);
			archivo.read(bloque,TAMANIO_LISTA_COD);
			dato="";
		}
		if((cantMaxCod-1)==((TIPO_DATO)(bloque[0])))
		{//es el ultimo lugar del vector
			TIPO_DATO tamanioArchivo,nroBloqueAuxSig;
			dato="";
			archivo.seekg(0, ios::end);	//se posiciona al final del archivo
			tamanioArchivo = archivo.tellg(); //indica en que pos del arch se encuentra (en byte)
			nroBloqueAuxSig =tamanioArchivo/TAMANIO_LISTA_COD;
			dato.replace(1,TAMANIO_COD_PROD,convertirChar(nroBloqueAuxSig,TAMANIO_COD_PROD));
			archivo.seekp(TAMANIO_LISTA_COD*nroBloqueAux ,ios::beg);
			strncpy(bloque,dato.c_str(),TAMANIO_LISTA_COD);
			archivo.write(bloque,TAMANIO_LISTA_COD);

			//guardo en el nuevo bloque el nuevo codigo
			archivo.seekp(TAMANIO_LISTA_COD*nroBloqueAuxSig ,ios::beg);
			
			dato=(unsigned char)1;
			dato+="0000";
			dato+=convertirChar(codProdIn,TAMANIO_COD_PROD);
			strncpy(bloque,dato.c_str(),TAMANIO_LISTA_COD);
			archivo.write(bloque,TAMANIO_LISTA_COD);
			codProdIn = nroBloqueAux ;
		}
		else
		{
		
			dato.append(bloque);
			
			int posicion=5;
			TIPO_DATO itemListaCod;
			for(int i=0; i<(int)dato[0];i++)
			{
				itemListaCod =string2TipoDato(dato.substr(posicion,TAMANIO_COD_PROD));
				
				if(itemListaCod>codProdIn)
				{
					codAux=itemListaCod;
					dato.replace(posicion,TAMANIO_COD_PROD,convertirChar(codProdIn,TAMANIO_COD_PROD));
					codProdIn = codAux;
				}
				posicion+=TAMANIO_COD_PROD;
			}
			dato[0]++;
			dato+=convertirChar(codProdIn,TAMANIO_COD_PROD);
			archivo.seekp(TAMANIO_LISTA_COD*nroBloqueAux ,ios::beg);
			strncpy(bloque,dato.c_str(),TAMANIO_LISTA_COD);
			archivo.write(bloque,TAMANIO_LISTA_COD);

		}
		//dato+=convertirChar(codProdIn,TAMANIO_COD_PROD);
		//dato.replace(cantMaxCod*TAMANIO_COD_PROD+1,TAMANIO_COD_PROD,convertirChar(codProdIn,TAMANIO_COD_PROD));

	}
	else
	{
		if((CANT_CODIGOS-1)==m_indice)
		{//es el ultimo lugar del vector
			TIPO_DATO tamanioArchivo;
			dato="";
			archivo.seekg(0, ios::end);	//se posiciona al final del archivo
			tamanioArchivo = archivo.tellg(); //indica en que pos del arch se encuentra (en byte)
			nroBloqueAux =tamanioArchivo/TAMANIO_LISTA_COD;
			archivo.seekp(TAMANIO_LISTA_COD*nroBloqueAux ,ios::beg);
			this->codProductos[this->m_indice++]=nroBloqueAux;
			//archivo.read(bloque,TAMANIO_LISTA_COD);
			dato=(unsigned char)1;
			dato+="0000";//nrobloque siguientes
			dato+=convertirChar(codProdIn,TAMANIO_COD_PROD);
			strncpy(bloque,dato.c_str(),TAMANIO_LISTA_COD);
			archivo.write(bloque,TAMANIO_LISTA_COD);
			codProdIn = nroBloqueAux ;
		}
		else
		{
//			TIPO_DATO codAux;
			this->codProductos[this->m_indice++]=codProdIn;
			std::sort(codProductos.begin(),codProductos.end(),::SortDesc());
//			dato="";
//			dato[0]=(unsigned char)m_indice;
//			dato+=convertirChar((int)clave.length(),TAMANIO_BYTE_DIN);
//			dato+=this->clave;
//			for(int i=0;i<m_indice;i++)
//				dato+=convertirChar(this->codProductos[i],TAMANIO_COD_PROD);
//			strncpy(bloque,dato.c_str(),TAMANIO_LISTA_COD);
		}
	}
//	archivo.seekp(TAMANIO_LISTA_COD*nroBloqueAux ,ios::beg);
//	archivo.write(bloque,TAMANIO_LISTA_COD);

}

TIPO_DATO CClaveSecundaria::getCodProd(int indice)
{
	return codProductos[indice];
}
void CClaveSecundaria::ordenar()
{
	vector<TIPO_DATO>				vectorClaves;

	if(codProductos[0]>codProductos[1])
	{
		for(int i=0;i<m_indice ;i++)
			vectorClaves.push_back(codProductos[(m_indice -1)-i]);

	//	for(int i=0;i<m_indice ;i++)
	//		cout<<"elemento del vector : "<<vectorClaves[i]<<endl;

		for(int i=0;i<m_indice ;i++)
			codProductos[i]=vectorClaves[i];
	}
//	for(int i=0;i<m_indice ;i++)
//		cout<<"elemento del vector : "<<m_nroBloques[i]<<endl;
}

#endif //__CLAVESECUNDARIA_H__

